package TravelAgent;

import java.net.*;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.io.*;

public class TravelAgent {

	
	
	public static void main(String[] args) {
		try
		{

			TravelAgent agent = new TravelAgent();
			agent.CommunicateWithClient();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	
	public void CommunicateWithClient()
	{
		try
		{
			ServerSocket server = new ServerSocket(3333);

			while(true)
			{
				Socket client = server.accept();
				BufferedReader input = new BufferedReader(new InputStreamReader(client.getInputStream()));
				PrintWriter output = new PrintWriter(client.getOutputStream(),true);

				//clientin tercihleri ögrenilir..
				Preferences preference = ClientPreferences(input); 			
	
				boolean isAvailable = IsAvailable(preference.GetStartDate(), preference.GetFinishDate(), preference.GetHotel(), preference.GetPeopleNumber());
	
				if(isAvailable == true)
				{
					output.println("0"); //hersey yolunda kodu
					String confirm = input.readLine();					
					if(confirm.compareTo("1000") == 0)
					{
						//dbye kaydet
						TravelAgentRmiClient rmi = new TravelAgentRmiClient();
						output.println(rmi.makeReservation(preference.GetStartDate(), preference.GetFinishDate(), preference.GetHotel(), Integer.toString(preference.GetPeopleNumber())));
						//eger dbye kaydedildiyse
						//yoksa output.println(false);						 
					}
				}
				else
				{
					//muhtemel itinerarylerin ne oldugu ögrenilir
					Itinerary[] itineraries = PossibleItineraries(preference.GetStartDate(), preference.GetFinishDate(), preference.GetHotel(), preference.GetPeopleNumber());
					
					if(itineraries.length > 0)
					{
						//olasi itinerarylerin tamami clienta gönderilir
						SendItinenariesToClient(output, itineraries);
	
						//kabul edilen itinerary okunur..
						String selectedItineraryIndex = GetAcceptedItinerary(input);
						if(selectedItineraryIndex != null) //bi index secilmis demektir
						{
							//dbye kaydet
							//eger dbye kaydedildiyse
							TravelAgentRmiClient rmi = new TravelAgentRmiClient();
							boolean result = rmi.makeSelectedReservation(preference.GetStartDate(), preference.GetFinishDate(), preference.GetHotel(),
														Integer.toString(preference.GetPeopleNumber()),itineraries[Integer.parseInt(selectedItineraryIndex)].GetActivity());
							output.println(result);
							//yoksa output.println(false);
						}
					}
					else
						output.println("2");  //istenilen tarihta hiçbir otelde bos yer yok
				}			
					output.close();
					input.close();							
			}			
		//	server.close();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	
	public Preferences ClientPreferences(BufferedReader input) throws IOException
	{		
		Preferences pre = new Preferences();
		String preferrences = input.readLine();
		pre.SplitPreferences(preferrences); 
		return pre;
	}

	public boolean IsAvailable(String startDate, String finishDate, String hotel, int peopleNumber) throws MalformedURLException, RemoteException, NotBoundException 
	{
		//Volkan db sorgusu ile istedigi tercihin olup olmadýgýný geridonderir
		TravelAgentRmiClient rmi = new TravelAgentRmiClient();
		return rmi.askHotel(startDate, finishDate, hotel, Integer.toString(peopleNumber));
		//Volkan db sorgusu ile istedigi tercihin olup olmadýgýný geridonderir 
		//return true;
	}

	 
	public Itinerary[] PossibleItineraries(String startDate, String finishDate, String hotel, int peopleNumber) throws MalformedURLException, RemoteException, NotBoundException
	{
		Itinerary[] itineraries = new Itinerary[3];
		//volkan
		TravelAgentRmiClient rmi = new TravelAgentRmiClient();	
		itineraries = rmi.findAlternatives(startDate, finishDate, hotel, Integer.toString(peopleNumber));
		//volkan
		
/*		for(int i = 0; i < itineraries.length; i++)
			itineraries[i] = new Itinerary(hotel, "opera"); //örnek. burada Volkan devreye girmeli
*/		
		return itineraries;
	}
	
	public void SendItinenariesToClient(PrintWriter output, Itinerary[] itineraries)
	{
		output.println("1:" + Integer.toString(itineraries.length));
		for(int i = 0; i<itineraries.length; i++)
			output.println(itineraries[i].ConCatItinerary()); 
	}
	
	//ekrem bastaki tercihi olsun ya da olmasýn sectigi itineraryi aynen gonderir
	public String GetAcceptedItinerary(BufferedReader input) throws IOException 
	{
		String s = input.readLine();
		System.out.println(s);
		if (s.compareTo("1001") == 0)//reject etmis
			return null; 
		else 
		{
			String array[] = s.split(":");
			return array[1];
		}
	}
}
